package com.ferry.serial.hessian;

import com.caucho.hessian.io.Hessian2Input;
import com.caucho.hessian.io.Hessian2Output;
import com.ferry.serial.api.InputBuf;
import com.ferry.serial.api.OutputBuf;
import com.ferry.serial.api.Serializer;
import com.ferry.serial.api.SerializerType;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

/**
 * Created by daiyong
 */
public class HessianSerializer extends Serializer {

	@Override
	public int code() {
		return SerializerType.HESSIAN.getCode();
	}

	@Override
	public <T> OutputBuf writeObject(OutputBuf outputBuf, T obj) {
		Hessian2Output output = new Hessian2Output(outputBuf.outputStream());

		try {
			output.writeObject(obj);
			output.flush();
			return outputBuf;
		} catch (IOException e) {
			throw new RuntimeException("hessian序列化失败");
		} finally {
			if (null != output) {
				try {
					output.close();
				} catch (IOException e) {
					throw new RuntimeException("关闭hessian output 失败");
				}
			}
		}
	}

	@Override
	public <T> byte[] writeObject(T obj) {
		ByteArrayOutputStream buf = new ByteArrayOutputStream(DEFAULT_BUF_SIZE);
		Hessian2Output output = new Hessian2Output(buf);

		try {
			output.writeObject(obj);
			output.flush();
			return buf.toByteArray();
		} catch (IOException e) {
			throw new RuntimeException("hessian序列化失败");
		} finally {
			if (null != output) {
				try {
					output.close();
				} catch (IOException e) {
					throw new RuntimeException("关闭hessian output 失败");
				}
			}
		}
	}

	@Override
	public <T> T readObject(InputBuf inputBuf, Class<T> cls) {
		Hessian2Input input = new Hessian2Input(inputBuf.inputStream());

		Object obj = null;
		try {
			obj = input.readObject(cls);
			return cls.cast(obj);
		} catch (IOException e) {
			throw new RuntimeException("hessian反序列化失败");
		} finally {
			try {
				input.close();
			} catch (IOException ignored) {}

			inputBuf.release();
		}

	}

	@Override
	public <T> T readObject(byte[] bytes, int offset, int length, Class<T> cls) {
		Hessian2Input input = new Hessian2Input(new ByteArrayInputStream(bytes, offset, length));
		try {
			Object obj = input.readObject(cls);
			return cls.cast(obj);
		} catch (IOException e) {
			throw new RuntimeException("hessian反序列化失败");
		} finally {
			try {
				input.close();
			} catch (IOException ignored) {}
		}
	}
}
